#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"../include/main.h"
#include"../include/narrtree.h"
#include"../include/hash.h"
#include"../include/fd.h"
#include"../include/bst.h"
#include"../include/mount_vfs.h"
#include"../include/copyfile.h"
#include"../include/create_vfs.h"
#include"../include/vfs_errorcodes.h"
#include"../include/constants.h"


char temp_source_path[MAX_PATH],temp_dest_path[MAX_PATH],temp_filename[MAX_PATH];
void copy_file(char source_path[],char dest_path[])
{
	ntree *search_return,*temp,*search_dest;
	char *dest=(char *)malloc(sizeof(char)*MAX_PATH);
	fdesc *copy;
	llist *list;
	char *k;
	int i;
	strcpy(temp_source_path,source_path);
	strcpy(temp_dest_path,dest_path);
	
	k=strrchr(temp_source_path,'/');
	if(k != NULL)
	{
		k++;
		if(*k == '\0')
		{
			temp_source_path[strlen(temp_source_path)-1]='\0';
			strcpy(source_path,temp_source_path);
		}
	}
	k=strrchr(temp_dest_path,'/');
	if(k != NULL)
	{
		k++;
		if(*k == '\0')
		{
			temp_dest_path[strlen(temp_dest_path)-1]='\0';
			strcpy(dest_path,temp_dest_path);
		}
	}
	i=0;
	while(i<strlen(source_path))
	{
		if(source_path[i] != dest_path[i])
			break;
		i++;
	}

	copy=(fdesc *)malloc(sizeof(fdesc));
	schflag=0;
	search_return=search_node(head,source_path);
	schflag=0;
	search_dest=search_node(head,dest_path);
	schflag=0;//any function can call search_node function of ntree
	if(mounted==0)
		printf("%s_FAILURE %s\n",glb_command,ERR_VFS_COPYFILE_05);
	else if(i==strlen(source_path))
		printf("%s_FAILURE %s\n",glb_command,ERR_VFS_COPYFILE_06);
	else if(search_return == NULL)
		printf("%s_FAILURE %s\n",glb_command,ERR_VFS_COPYFILE_01);
	else if(search_dest == NULL)
		printf("%s_FAILURE %s\n",glb_command,ERR_VFS_COPYFILE_02);
	else if(search_dest->file_desc->filetype==0)
		printf("%s_FAILURE %s\n",glb_command,ERR_VFS_COPYFILE_03);
	else
	{
		if(search_return->file_desc->filetype==1)
		{
		
			if(search_return->first==NULL)
			{
				if(strcmp(dest_path,"/"))
					dest=strcat(dest_path,"/");
				else
					strcpy(dest,dest_path);
				strcat(dest,search_return->file_desc->filename);
				strcpy(copy->filepath,dest);
				strcpy(copy->filename,search_return->file_desc->filename);
				copy->filetype=1;
				copy->file_size=search_return->file_desc->file_size;
				copy->blk_num=search_return->file_desc->blk_num;
				if(local_used_fd < local_max_fd)
				{
					head=insert_ntree(head,copy);
					list=insert(copy);
					local_used_fd++;
					printf("copyfile_SUCCESS\n");
				}
				else
					printf("%s_FAILURE %s\n",glb_command,ERR_VFS_COPYFILE_04);
			}
			else
			{
				//update_copy_path(search_return,dest_path);
				k=strrchr(temp_source_path,'/');
				if(k != NULL)
				{
					//*k='\0';
					k++;
					strcpy(temp_filename,k);
					copydir(search_return,dest_path);
					printf("copyfile_SUCCESS\n");
				}
			}					
		}

		if(search_return->file_desc->filetype==0)
		{
			if(strcmp(dest_path,"/"))
				dest=strcat(dest_path,"/");
			else
				strcpy(dest,dest_path);
			strcat(dest,search_return->file_desc->filename);
			strcpy(copy->filepath,dest);
			strcpy(copy->filename,search_return->file_desc->filename);
			copy->filetype=0;
			copy->file_size=search_return->file_desc->file_size;
			copy->blk_num=search_return->file_desc->blk_num;
			if(local_used_fd < local_max_fd)
			{
				head=insert_ntree(head,copy);
				list=insert(copy);
				local_used_fd++;
				printf("copyfile_SUCCESS\n");
			}
			else
				printf("%s_FAILURE %s\n",glb_command,ERR_VFS_COPYFILE_04);
		}
		//traverse(head);
	}
}

void copydir(ntree *sch,char ds_path[])
{
	ntree *temp4,*q;
	fdesc *copy;
	llist *list;
	char *pch;
	char bakup[MAX_PATH],inbakup[MAX_PATH];
	char *dest=(char *)malloc(sizeof(char)*MAX_PATH);
	q=sch;
	if(q!=NULL)
	{
		strcpy(bakup,ds_path);
		temp4=q;
		do
		{
			//printf("********%s\t %d\n",temp4->file_desc->filepath,temp4->file_desc->filetype);
			copy=(fdesc *)malloc(sizeof(fdesc));
			if(copy==NULL)
			{
				strcpy(inbakup,ds_path);
				pch=strrchr(temp4->file_desc->filepath,'/');
				strcat(ds_path,pch);
				strcpy(copy->filepath,ds_path);
				pch++;
				strcpy(copy->filename,temp4->file_desc->filename);
			
				if(local_used_fd < local_max_fd)
				{
					if(temp4->file_desc->filetype == 1)
					{
						copy->filetype=1;
						copy->blk_num=temp4->file_desc->blk_num;
					}
					else
					{
						copy->filetype=0;
						copy->blk_num=glb_blk_num;
						*(block_arr+glb_blk_num)=glb_blk_num;
						strcpy(data[glb_blk_num],data[temp4->file_desc->blk_num]);
						//printf("data[%d]==%s\n",glb_blk_num,data[glb_blk_num]);
						glb_blk_num++;
					}
					copy->file_size=temp4->file_desc->file_size;
				
					head=insert_ntree(head,copy);
					list=insert(copy);
					local_used_fd++;
					if(strcmp(temp4->file_desc->filepath,temp_source_path) && strcmp(temp4->file_desc->filename,temp_filename))
					copydir(temp4->first,copy->filepath);
					if(!strcmp(temp4->file_desc->filepath,temp_source_path) && !strcmp(temp4->file_desc->filename,temp_filename))
						temp4=temp4->first;
					else
						temp4=temp4->next;
					strcpy(ds_path,inbakup);
				}
				else
				{
					printf("%s_FAILURE %s\n",glb_command,ERR_VFS_COPYFILE_04);
					//temp4=NULL;
					//q=NULL;
					break;
				}
			}
			else
			{
				printf("%s_FAILURE %s\n",glb_command,ERR_VFS_COPYFILE_04);
				break;
			}
		}while(temp4!=NULL);
	}
}
